package com.defense.chat;
/**
* @类名  ServerManager.java
* @作者  jinbanglong
* @版本  V1.0
* @日期  2019年6月27日-下午7:56:17
* @描述  
*
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.defense.util.Regex;


public class ServerManager {
   public static void main(String[] args) {
	   new Thread(new ServerSend()).start();
	   try {
		  System.out.println("欢迎来到聊天室。。。");
	      ServerSocket serverSocket = new ServerSocket(8888);
	      //使用线程池
	      ExecutorService executorService = Executors.newFixedThreadPool(20);
	      for(int i = 0;i < 20;i++){
	        Socket socket = serverSocket.accept();
	        System.out.println("客户端:"+socket+"已连接到服务器");
	        
	        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
	        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
	        DataInputStream console = new  DataInputStream(socket.getInputStream());
	        DataOutputStream DS = new DataOutputStream(socket.getOutputStream());
	        executorService.execute(new Server(br,bw,console,DS));
	      }
	      executorService.shutdown();
	      serverSocket.close();
	    } catch (IOException e) {
	      e.printStackTrace();
	    }
   }
}

class Server implements Runnable{
	static HashMap<String,BufferedWriter> user = new HashMap<>();
	private BufferedReader br;
	private BufferedWriter bw;
	private DataInputStream console;
	private DataOutputStream DS;
	private String userName;
	
	public Server() {
	}

	public Server(BufferedReader br, BufferedWriter bw ,DataInputStream console,DataOutputStream DS) {
		this.br = br;
		this.bw = bw;
		this.console = console;
		this.DS = DS;
		
		try {
			String uName = br.readLine();
			user.put(uName, bw);
			userName=uName;
			
			bw.write("G-【系统】说："+uName+"进入聊天室\n");
	        bw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public BufferedReader getBr() {
		return br;
	}

	public void setBr(BufferedReader br) {
		this.br = br;
	}

	public BufferedWriter getBw() {
		return bw;
	}

	public void setBw(BufferedWriter bw) {
		this.bw = bw;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	@Override
	public void run() {
		while(true) {
			try {
				String msg = receive();
				if("exit".equals(msg)) {
					System.err.println(userName+"已离开聊天室");
					continue;
				}
				if(msg.startsWith("@")) {
					privateChat(msg);
				}else {
					groupChat(msg);
				}
			} catch (IOException e) {
//				e.printStackTrace();
				break;
			}
		}
	}
	
	//群聊处理方法
	protected void groupChat(String msg) throws IOException {
		Set<String> uname = user.keySet();
		Iterator<String> it = uname.iterator();
		//-f:
		msg=msg.replaceAll(":", "：");//英文逗号，替换为中文
		int ind = msg.indexOf("：");
		//-f
//		System.out.println(msg);
		if(ind!=-1) {
			String name = msg.substring(0, ind);
			if(name.matches(Regex.fileGroup)) {
//				System.out.println("进来啦");
				String url = upload();
				
//				bw = user.get(userName);
				//send(url);//返回上传地址,客户端报错
				msg=url;
			}
		
		}
		
		
		String content ="G-【"+userName+"】说："+msg;
		System.out.println(content);//打印在服务端
		while(it.hasNext()) {
			String next = it.next();
			if(next!=userName) {
				bw = user.get(next);
				
				send(content);
			}
		}
	}
	//私聊处理方法
	protected void privateChat(String msg) throws IOException {
		msg=msg.replaceAll(":", "：");//英文逗号，替换为中文
		int ind = msg.indexOf("：");
		//@jinbl-f：文件            uName=jinbl-F
		if(ind!=-1) {
			String name = msg.substring(0, ind);
//			System.out.println("上传"+name);
			if(name.matches(Regex.fileCommand)) {
				String url = upload();//上传完成将路径返回客户端，进行二次发送，
				
				int index=name.indexOf("-");//名字的截取需要区分
				String uName=msg.substring(0, index);//名字的截取需要区分
				send(uName+":"+url);//返回上传地址
				
				
				uName=uName.substring(1);//名字的截取需要区分
//				System.out.println(uName);
				bw = user.get(uName);
				String content = "P-【"+userName+"】对你说："+url;
				send(content);
				
				System.out.println(content.replaceFirst("你", uName));//打印在服务端
			}else {
				String uName=msg.substring(1, ind);//名字的截取需要区分
//				System.out.println(uName);
				bw = user.get(uName);
				String content = "P-【"+userName+"】对你说："+msg.substring(ind+1);
				send(content);
				
				System.out.println(content.replaceFirst("你", uName));//打印在服务端
			}
		}else {
			return;
		}
		
		
	}
	protected String receive() throws IOException {
		String msg = br.readLine();
		return msg;
	}
	protected void send(String msg) throws IOException {
		bw.write(msg+"\n");
		bw.flush();
	}
	public String upload() {
//		System.out.println("服务端上传开始");
		 try {
			 	bw = user.get(userName);
				String dir ="img";
				String path = "D:\\dev\\apache-tomcat-8.5.42\\webapps";
				String fname=console.readUTF();
//				System.out.println(fname);
				String newName = path+"\\"+dir+"\\"+fname;
				File file = new File(newName); 
				FileOutputStream fos = new FileOutputStream(file);
				DataOutputStream dd = new DataOutputStream(fos);
				long length= console.readLong();
				byte[] b = new byte[8192];
				int len;
				int lens=0;
				while(true) {
					len=console.read(b);
					dd.write(b, 0, len);
					lens+=len;
					dd.flush();
					
					String progress="上传进度："+lens*100/length+"%";
					send(progress);  //进度显示在客户端
					//System.out.println(progress);
					if(lens>=length){
						break ;
					}
				}
				dd.close();
				fos.close();
				//向客户端返回上传地址
				
				InetAddress addr = InetAddress.getLocalHost(); 
				String url="http://"+addr.getHostAddress()+":8080/"+dir+"/"+fname;
				return url;
		 } catch (Exception e1) {
			e1.printStackTrace();
		}
		
		 return null;
	}
	
	
	
	
	
}
class ServerSend implements Runnable{
	@Override
	public void run() {
		Server ser = new Server();
		ser.setUserName("系统");
		Scanner sc = new Scanner(System.in);
		while(true) {
			String msg = sc.nextLine();
			if(msg.equals("")) {
				continue;
			}
			try {
				if(msg.startsWith("@")) {
					ser.privateChat(msg);
				}else {
					ser.groupChat(msg);
				}
			} catch (IOException e) {
//				e.printStackTrace();
				break;
			}
		}
	}
	
}


